package gate

import (
	"leaf/core/log"
	"leaf/core/network"
	"time"
)

var Processor = NewMsgProcessor()

type Gate struct {
	MaxConnNum      int
	PendingWriteNum int
	MaxMsgLen       uint32

	// websocket
	WSAddr      string
	HTTPTimeout time.Duration
	CertFile    string
	KeyFile     string

	// tcp
	TCPAddr      string
	LenMsgLen    int
	LittleEndian bool
	WsServer     *network.WsServer
	TcpServer    *network.TcpServer
	// GatAgent
	GoLen              int
	TimerDispatcherLen int
	AsynCallLen        int
	ChanRPCLen         int
	OnAgentInit        func(Agent)
	OnAgentDestroy     func(Agent)
}

func NewGate(addr string) *Gate {
	gs := new(Gate)
	gs.LittleEndian = true
	gs.WSAddr = addr
	gs.PendingWriteNum = 1
	return gs
}

func (gate *Gate) Init(Service interface{}) {

}

func (gate *Gate) GetThreadNum() int32 {
	return 1
}

func (gate *Gate) Run(closeSig chan bool) {
	createAgant := func(wsConn network.Conn) network.Agent {
		return &GatAgent{
			conn:     wsConn,
			msgLimit: map[uint16]int64{},
		}
	}
	if gate.WSAddr != "" {
		gate.WsServer = network.NewWsServer(gate.WSAddr, gate.MaxConnNum, createAgant)
	}

	if gate.TCPAddr != "" {
		gate.TcpServer = network.NewTcpServer(gate.TCPAddr, gate.MaxConnNum, createAgant)
	}

	if gate.WsServer != nil {
		gate.WsServer.Start(false)
	}
	if gate.TcpServer != nil {
		gate.TcpServer.Start(false)
	}
}

func (gate *Gate) Destroy() {
	log.Release("gate destroy...")
	if gate.WsServer != nil {
		gate.WsServer.Close()
		log.Release("gate ws server close")
	}
	if gate.TcpServer != nil {
		gate.TcpServer.Close()
		log.Release("gate tpc server close")
	}
	AgentDestroy()
}
